<template>

  <div ref="topoRef" id="podTopo" :style="{ flexGrow: 1, overflow: 'hidden' }"></div>
  <NodeDetail :visible="nodeDetailVisible" @on-close="() => nodeDetailVisible = false" :nodeInfo="nodeInfo"
    :queryTime="queryTime" :srcNodes="srcNodes" apiType="topology" drawerType="pod" />

</template>

<script setup>
import { nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { minBy, maxBy, uniqBy, forEach } from 'lodash'
import G6 from '@antv/g6';
import NodeDetail from '../../index.vue'
import { graphFocusNode } from '@/views/containerSystem/topology/topoService';
import { getNodeAndEdgeStatus } from './utils';
import { podEdgeTooltip, podNameTooltip } from './PodTopoComponent';
import { map } from 'lodash';
const props = defineProps({
  topoData: {
    type: Object,
    default: () => ({})
  },
  isFullScreen: Boolean,
  queryTime: {
    type: Object,
    default: () => ({})
  }
})
const topoRef = ref()
const graph = ref()
const nodeDetailVisible = ref(false)
const nodeInfo = ref({})
const srcNodes = ref([])
const requestTotal = reactive({ min: 0, max: 0 })
// 当监听到window对象或者container的大小发生变化是，改变画布大小

const changeGraphSize = () => {
  if (graph.value && topoRef.value) {
    nextTick(() => {
      const { clientWidth, clientHeight } = topoRef.value;
      console.log(clientWidth, 'clientWidth',clientHeight);

      graph.value.changeSize(clientWidth, clientHeight);
    })
    // this.graph.fitCenter()
  }
};

// 设置线上最大最小请求量数据
const setEdgeRequestTotalRange = () => {
  const { topoData } = props;
  requestTotal.min =
    minBy(topoData.edges, "requestTotal")?.requestTotal || 0;
  requestTotal.max =
    maxBy(topoData.edges, "requestTotal")?.requestTotal || 0;
};

const draw = () => {
  const { topoData } = props;
  console.log(topoData.nodes.length, "topo");

  if (!topoData.nodes.length) {
    topoRef.value.innerHTML = "";
    return;
  }
  const { nodes, edges } = topoData;
  const data = { nodes, edges };
  G6.Util.processParallelEdges(
    data.edges,
    30,
    "quadratic",
    undefined,
    "loop"
  );

  const width = topoRef.value.clientWidth;
  const height = topoRef.value.clientHeight;
  topoRef.value.innerHTML = "";

  const graphInst = new G6.Graph({
    container: topoRef.value || 'podTopo',
    width,
    height,
    fitCenter: true,
    autoPaint: false,
    plugins: [podNameTooltip, podEdgeTooltip],
    modes: {
      default: [
        {
          type: "zoom-canvas",
          minZoom: 0.5,
          maxZoom: 5,
        },
        {
          type: "drag-node",
          onlyChangeComboSize: true,
        },
        "drag-combo",
        "drag-canvas",
      ],
      showComponent: [],
    },
    defaultNode: {
      type: "custom-node",
    },
    defaultEdge: {
      style: {
        endArrow: {
          path: G6.Arrow.triangle(5, 5, 0),
          fill: "#AAAAAA",
        },
        lineWidth: 1,
        lineAppendWidth: 5,
        stroke: "#AAAAAA",
      },
    },
  });
  graphInst.data(data);
  graphInst.render();

  graph.value = graphInst;

  graphInst.on("node:mouseenter", (evt) => {
    const { item } = evt;
    graphFocusNode(item, graphInst);
    graphInst.setItemState(item, "hover", true);
  });
  graphInst.on("node:mouseleave", (evt) => {
    const { item } = evt;
    graphFocusNode("", graphInst);
    graphInst.setItemState(item, "hover", false);
  });
  graphInst.on("node:click", (evt) => {
    const { item } = evt;
    const model = item.getModel();

    if (model.id === "external") {
      return;
    }
    const inEdges = item.getInEdges();
    let nodes = [];
    if (model?.extraSrcNodes?.length) {
      nodes = model.extraSrcNodes;
    } else {
      // 需要过滤掉源端为external的节点(貌似不需要过滤掉了，这里不会有external点，先保留吧)
      nodes = map(inEdges, (edge) => edge.getSource().getModel()).filter(
        (node) => node.id !== "external"
      );
    }
    //   console.log(srcNodes, "nodes",model);

    nodeInfo.value = model
    srcNodes.value = uniqBy(nodes, 'id')
    nodeDetailVisible.value = true
    // this.setState({
    //   nodeInfo: model,
    //   srcNodes: uniqBy(srcNodes, "id"),
    //   nodeDetailVisible: true,
    // });

  });

  setEdgeLineWidth(graph.value);
};

// afterrender后设置线的粗细
const setEdgeLineWidth = (graph) => {
  graph.setAutoPaint(false);
  const edges = graph.getEdges();
  const segment = (requestTotal.max - requestTotal.min) / 5;
  forEach(edges, (edge) => {
    const edgeModel = edge.getModel();
    const edgeStatus = getNodeAndEdgeStatus(edgeModel);
    const { requestTotal } = edgeModel;
    const lineWidth = segment
      ? Math.ceil((requestTotal - requestTotal.min) / segment)
      : 1;

    edgeModel.style.stroke = edgeStatus ? "#F7313B" : "#AAAAAA";
    edgeModel.style.lineWidth = lineWidth || 1;
    edgeModel.style.endArrow = {
      path: G6.Arrow.triangle(4 + lineWidth, 4 + lineWidth, 0),
      fill: edgeStatus ? "#F7313B" : "#AAAAAA",
    };
    edgeModel.style.cursor = "pointer";

    graph.updateItem(edge, edgeModel);
  });
  graph.paint();
  graph.setAutoPaint(true);
};
defineExpose({
  graph: graph
})
onMounted(() => {
  setEdgeRequestTotalRange()
  draw()
  window.addEventListener('resize', changeGraphSize)
})
onUnmounted(() => {
  window.removeEventListener('resize', changeGraphSize)
})
watch(() => props.topoData, () => {
  setEdgeRequestTotalRange()
  draw()
})
watch(() => props.isFullScreen, changeGraphSize)
</script>

<style scoped lang="scss"></style>
